package com.controller.user;

import com.common.ErrorCodeEnum;
import com.common.anntation.Log;
import com.common.emums.BusinessType;
import com.common.excel.ExcelUtil;
import com.common.exception.BusinessException;
import com.common.utils.*;
import com.core.springSecurity.common.SecurityUtils;
import com.core.springSecurity.model.LoginUserDetails;
import com.github.pagehelper.PageInfo;
import com.model.base.PageResult;
import com.model.base.Result;
import com.model.domain.device.GetDeviceObdBaseInfoDO;
import com.model.domain.device.GetDeviceObdExFactoryBatchBindInfoDO;
import com.model.domain.user.GetUserInfoDO;
import com.model.dto.device.deviceOBDInfo.ExportBindDeviceListDTO;
import com.model.dto.user.factory.*;
import com.model.pojo.device.DeviceObdBaseInfo;
import com.model.pojo.device.DeviceObdExFactoryBatchBindInfo;
import com.model.pojo.device.DeviceObdExFactoryBatchInfo;
import com.model.pojo.sys.SysUser;
import com.model.pojo.system.SystemDeviceModelInfo;
import com.model.pojo.user.UserInfo;
import com.model.vo.device.deviceOBDInfo.ExportBindDeviceListVO;
import com.model.vo.user.factory.bindDevice.BindDeviceVO;
import com.model.vo.user.factory.bindDevice.ErrorBindDeviceVO;
import com.model.vo.user.factory.getBindListByFactoryUserId.GetBindListByFactoryUserIdVO;
import com.model.vo.user.factory.getFactoryList.GetFactoryListVO;
import com.model.vo.user.factory.getVeccAccountInfo.GetVeccAccountInfoVO;
import com.service.device.DeviceObdBaseInfoService;
import com.service.device.DeviceObdExFactoryBatchBindInfoService;
import com.service.device.DeviceObdExFactoryBatchInfoService;
import com.service.sys.SysUserService;
import com.service.system.SystemDeviceModelInfoService;
import com.service.system.SystemDomainInfoService;
import com.service.user.UserInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @Description
 * @Author tm
 * @Date 2023-09-04 8:51
 **/
@Api(tags = {"生产厂商管理"})
@Slf4j
@RestController
@RequestMapping("/v1/user/factory")
@RequiredArgsConstructor
public class FactoryController {
    private final UserInfoService userInfoService;
    private final SysUserService sysUserService;
    private final DeviceObdBaseInfoService deviceObdBaseInfoService;
    private final DeviceObdExFactoryBatchBindInfoService deviceObdExFactoryBatchBindInfoService;
    private final DeviceObdExFactoryBatchInfoService deviceObdExFactoryBatchInfoService;
    private final SystemDeviceModelInfoService systemDeviceModelInfoService;
    @Log(title = "生产厂商管理-生产厂商列表", businessType = BusinessType.INSERT)
    @ApiOperation(value = "生产厂商列表")
    @PostMapping("/getFactoryList")
    public Result<PageResult<List<GetFactoryListVO>>> getPcbDeviceList(@RequestBody @Valid GetFactoryListDTO dto){
        LoginUserDetails loginUserDetails = SecurityUtils.getLoginUser();
        int curUserType = loginUserDetails.getUser().getUserType();
        List<GetFactoryListVO> voList = new ArrayList<>();
        GetUserInfoDO getUserInfoDO = EntityConversionUtil.copy(dto,GetUserInfoDO.class);
        if(curUserType == Constants.SysUserUserType.TYPE_播种机查看权限){//如果当前登录帐号为播种机查看权限
            getUserInfoDO.setDeviceType(3);//查看播种机的厂家
        }
        getUserInfoDO.setSortRow("registerTime");
        getUserInfoDO.setUserType(1);
        List<UserInfo> userList = userInfoService.getPageList(getUserInfoDO);
        if(userList!=null && userList.size()>0){
            userList.forEach(item->{
                GetFactoryListVO vo = EntityConversionUtil.copy(item,GetFactoryListVO.class);
                vo.setCreateTime(item.getRegisterTime());
                voList.add(vo);
            });
        }
        PageInfo<UserInfo> pageInfo = new PageInfo<>(userList);
        PageResult<List<GetFactoryListVO>> build = PageResult.<List<GetFactoryListVO>>builder().result(voList).pageInfo(pageInfo).build();
        return Result.suc(build);
    }

    @Log(title = "生产厂商管理-新增和修改生产厂商", businessType = BusinessType.INSERT)
    @ApiOperation(value = "新增和修改生产厂商")
    @PostMapping("/saveFactory")
    public Result<Objects> saveFactory(@RequestBody @Valid SaveFactoryDTO dto){
        LoginUserDetails loginUserDetails = SecurityUtils.getLoginUser();
        int curUserType = loginUserDetails.getUser().getUserType();
        int deviceType = 1;//当前生厂厂商帐号所属设备类型
        if(curUserType == Constants.SysUserUserType.TYPE_播种机查看权限){//为播种机
            deviceType = 3;
        }
        int num = 0;
        long userId = 0;
        if(dto.getId()!=0 && dto.getId()!=null){ //修改生厂厂商帐号信息
            UserInfo userInfo = userInfoService.getById(dto.getId());
            if(userInfo == null){
                return Result.fail("9999","该生产厂商不存在");
            }
            userInfo.setName(dto.getName());
            userInfo.setAllowSecondSupply(dto.getAllowSecondSupply());
            userInfo.setPassword(MD5.encode(dto.getPassword(), "utf-8"));
            userInfo.setCompanyName(dto.getCompanyName());
            userInfo.setCompanyCode(dto.getCompanyCode());
            userInfo.setLicenseUrl(dto.getLicenseUrl());
            userInfo.setFileUrls(dto.getFileUrls());
            userInfo.setForwardAccount(dto.getForwardAccount());
            userInfo.setForwardPwd(dto.getForwardPwd());
            userInfo.setDeviceType(deviceType);
            num = userInfoService.update(userInfo);
            userId = userInfo.getId();
        }else{//新增生厂厂家
            UserInfo userInfo = userInfoService.getByCellphone(dto.getCellphone());
            if(userInfo!=null){
                if(userInfo.getUserType()!=1){
                    return Result.fail("9999","该帐号已被注册过");
                }
                userInfo.setPassword(MD5.encode(dto.getPassword(), "utf-8"));
                userInfo.setCompanyName(dto.getCompanyName());
                userInfo.setCompanyCode(dto.getCompanyCode());
                userInfo.setLicenseUrl(dto.getLicenseUrl());
                userInfo.setFileUrls(dto.getFileUrls());
                userInfo.setForwardAccount(dto.getForwardAccount());
                userInfo.setForwardPwd(dto.getForwardPwd());
                userInfo.setPassword(MD5.encode(dto.getPassword(), "utf-8"));
                userInfo.setAllowSecondSupply(dto.getAllowSecondSupply());
                userInfo.setDeviceType(deviceType);
                num = userInfoService.update(userInfo);
                userId = userInfo.getId();
            }else{
                userInfo = new UserInfo();
                userInfo.setName(dto.getName());
                userInfo.setPassword(MD5.encode(dto.getPassword(), "utf-8"));
                userInfo.setCellphone(dto.getCellphone());
                userInfo.setUserType(1);
                userInfo.setAllowSecondSupply(dto.getAllowSecondSupply());
                userInfo.setPassword(MD5.encode(dto.getPassword(), "utf-8"));
                userInfo.setCompanyName(dto.getCompanyName());
                userInfo.setCompanyCode(dto.getCompanyCode());
                userInfo.setLicenseUrl(dto.getLicenseUrl());
                userInfo.setFileUrls(dto.getFileUrls());
                userInfo.setForwardAccount(dto.getForwardAccount());
                userInfo.setForwardPwd(dto.getForwardPwd());
                userInfo.setDeviceType(deviceType);
                userInfo = userInfoService.save(userInfo);
                if(userInfo.getId()>0){
                    num = 1;
                    userId = userInfo.getId();
                }
            }
        }
        if(num > 0){
            SysUser sysUser = sysUserService.getByMobile(dto.getCellphone());
            if(sysUser ==null){
                sysUser = new SysUser();
                sysUser.setUserId(userId);
                sysUser.setSysDeptId(1l);
                sysUser.setName(dto.getCellphone());
                sysUser.setMobile(dto.getCellphone());
                sysUser.setFullName(dto.getName());
                sysUser.setPassword(PasswordUtils.encode(Md5Utils.toUpperCase32(dto.getPassword())));
                sysUser.setStatus(1);
                if(deviceType ==1){
                    sysUser.setUserType((byte)Constants.SysUserUserType.TYPE_TBOX生产厂家);
                }else if(deviceType ==3){
                    sysUser.setUserType((byte)Constants.SysUserUserType.TYPE_播种机生产厂家);
                }
                sysUserService.create(sysUser);
            }else{
                sysUser.setUserId(userId);
                sysUser.setSysDeptId(1l);
                sysUser.setName(dto.getCellphone());
                sysUser.setMobile(dto.getCellphone());
                sysUser.setFullName(dto.getName());
                sysUser.setPassword(PasswordUtils.encode(Md5Utils.toUpperCase32(dto.getPassword())));
                sysUser.setStatus(1);
                if(deviceType ==1){
                    sysUser.setUserType((byte)Constants.SysUserUserType.TYPE_TBOX生产厂家);
                }else if(deviceType ==3){
                    sysUser.setUserType((byte)Constants.SysUserUserType.TYPE_播种机生产厂家);
                }
                sysUserService.update(sysUser);
            }
            SysUser aSysUser = sysUserService.getByName("a_"+dto.getCellphone());
            if(aSysUser == null){
                //创建一个厂家配置帐号
                aSysUser = new SysUser();
                aSysUser.setUserId(userId);
                aSysUser.setSysDeptId(1l);
                aSysUser.setName("a_"+dto.getCellphone());
                aSysUser.setMobile(dto.getCellphone());
                aSysUser.setFullName(dto.getName());
                aSysUser.setPassword(PasswordUtils.encode(Md5Utils.toUpperCase32(dto.getPassword())));
                aSysUser.setStatus(1);
                aSysUser.setUserType((byte)4);
                sysUserService.create(aSysUser);
            }
        }
        return Result.suc();
    }


    @Log(title = "生产厂商管理 - 绑定设备", businessType = BusinessType.IMPORT)
    @ApiOperation(value = "绑定设备")
    @PostMapping(value = "/bindDevice")
    public Result<BindDeviceVO> bindDevice(@RequestParam("file") MultipartFile excelFile, @RequestParam("factoryUserId") Long factoryUserId) {
        List<BindDeviceDTO> excelList = ExcelUtil.readExcel(excelFile, 1, 1, BindDeviceDTO.class);
        if (StringUtils.isNull(excelList) || excelList.size() <= 0) {
            throw new BusinessException(ErrorCodeEnum.EXCEL_NOT_FOUNT);
        }
        List<ErrorBindDeviceVO> errorVoList = new ArrayList<>();
        List<DeviceObdBaseInfo> list = new ArrayList<>();
        System.out.println("excel总数：" + excelList.size());
        excelList = excelList.stream().filter(o -> {
            System.out.println("IMEI："+o.getImei() );
            String imei = o.getImei();//Utils.verifyNullMember(o,"dtu");
//            System.out.println("设备号："+dtu );
            if ("".equals(imei)) {
                errorVoList.add(EntityConversionUtil.copy(o, ErrorBindDeviceVO.class).errMsg("字段" + imei + "为空"));
                log.error("字段{}为空", imei);
                return false;
            }
            List<DeviceObdBaseInfo> baseList = deviceObdBaseInfoService.getByImei(imei);
            if (baseList == null || baseList.size() == 0) {
                errorVoList.add(EntityConversionUtil.copy(o, ErrorBindDeviceVO.class).errMsg("字段" + imei + "该设备不存在"));
                log.error("字段{}设备不存在", imei);
                return false;
            }
            if (baseList.size()>1) {
                errorVoList.add(EntityConversionUtil.copy(o, ErrorBindDeviceVO.class).errMsg("字段" + imei + "有多条记录"));
                log.error("字段{}有多条记录", imei);
                return false;
            }
            DeviceObdBaseInfo baseInfo = baseList.get(0);
            if(baseInfo!=null && (baseInfo.getBatchId() == null || baseInfo.getBatchId() == 0)){
                errorVoList.add(EntityConversionUtil.copy(o, ErrorBindDeviceVO.class).errMsg("字段" + imei + "该设备未出厂"));
                log.error("字段{}该设备未出厂", imei);
                return false;
            }
            if (baseInfo != null &&baseInfo.getFactoryUserId()!=null && baseInfo.getFactoryUserId() > 0) {
                errorVoList.add(EntityConversionUtil.copy(o, ErrorBindDeviceVO.class).errMsg("字段" + imei + "该设备已绑定厂家"));
                log.error("字段{}该设备已绑定厂家", imei);
                return false;
            }
            list.add(baseInfo);
            return true;
        }).collect(Collectors.toList());
        System.out.println("设备总数： " + list.size());
        List<DeviceObdBaseInfo> baseList = new ArrayList<>();
        List<String> idList = new ArrayList<>();
        long exFactoryUserId = 0l;
        for(DeviceObdBaseInfo item:list) {
            item.setFactoryUserId(factoryUserId);
            item.setLastModifiedTime(new Date());
            baseList.add(item);
            idList.add(item.getId()+"");
            if(exFactoryUserId==0 && item.getBatchId()!=null && item.getBatchId()>0){
                DeviceObdExFactoryBatchInfo batchInfo = deviceObdExFactoryBatchInfoService.getById(item.getBatchId());
                if(batchInfo!=null && batchInfo.getFactoryUserId()!=null && batchInfo.getFactoryUserId()>0){
                    exFactoryUserId = batchInfo.getFactoryUserId();
                }
            }
        }
        if (baseList.size() > 0) {
            deviceObdBaseInfoService.updateList(baseList);
            String factoryName = "";
            UserInfo userInfo = userInfoService.getById(factoryUserId);
            if(userInfo!=null)factoryName = userInfo.getName();
            DeviceObdExFactoryBatchBindInfo bindInfo = new DeviceObdExFactoryBatchBindInfo();
            bindInfo.setFactoryUserId(factoryUserId);
            bindInfo.setBatchId(0l);
            bindInfo.setExFactoryUserId(exFactoryUserId);
            bindInfo.setNumber(idList.size());
            String dtus = String.join(";",idList);
            bindInfo.setDtus(dtus);
            bindInfo.setFactoryName(factoryName);
            deviceObdExFactoryBatchBindInfoService.save(bindInfo);
        }
        return Result.suc(BindDeviceVO.builder().importSuccess(baseList.size()).errorList(errorVoList).build());
    }



    @Log(title = "生产厂商管理-绑定记录", businessType = BusinessType.INSERT)
    @ApiOperation(value = "绑定记录")
    @PostMapping("/getBindListByFactoryUserId")
    public Result<PageResult<List<GetBindListByFactoryUserIdVO>>> getBindListByFactoryUserId(@RequestBody @Valid GetBindListByFactoryUserIdDTO dto) {
        List<GetBindListByFactoryUserIdVO> voList = new ArrayList<>();
        GetDeviceObdExFactoryBatchBindInfoDO getDeviceObdExFactoryBatchBindInfoDO = EntityConversionUtil.copy(dto,GetDeviceObdExFactoryBatchBindInfoDO.class);
        if(dto.getFactoryUserId()!=null && dto.getFactoryUserId() !=0){
            UserInfo userInfo = userInfoService.getById(dto.getFactoryUserId());
            if(userInfo!=null){
                getDeviceObdExFactoryBatchBindInfoDO.setFactoryUserId(null);
                if(userInfo.getAllowSecondSupply() == 1){
                    getDeviceObdExFactoryBatchBindInfoDO.setExFactoryUserId(dto.getFactoryUserId());
                }else{
                    getDeviceObdExFactoryBatchBindInfoDO.setFactoryUserId(dto.getFactoryUserId());
                }
            }
        }
        getDeviceObdExFactoryBatchBindInfoDO.setSortRow("createTime");
        List<DeviceObdExFactoryBatchBindInfo> bindList = deviceObdExFactoryBatchBindInfoService.getPageList(getDeviceObdExFactoryBatchBindInfoDO);
        if(bindList!=null && bindList.size()>0){
            voList = EntityConversionUtil.copyList(bindList,GetBindListByFactoryUserIdVO.class);
        }
        PageInfo<DeviceObdExFactoryBatchBindInfo> pageInfo = new PageInfo<>(bindList);
        PageResult<List<GetBindListByFactoryUserIdVO>> build = PageResult.<List<GetBindListByFactoryUserIdVO>>builder().result(voList).pageInfo(pageInfo).build();
        return Result.suc(build);
    }


    @Log(title = "生产厂商管理 -  导出绑定的设备列表", businessType = BusinessType.EXPORT, isSaveResponseData = false)
    @ApiOperation(value = "导出绑定的设备列表")
    @PostMapping(value = "/exportBindDeviceList")
    public void exportBindDeviceList(@RequestBody @Valid ExportBindDeviceListDTO dto, HttpServletResponse response) throws BusinessException {
        List<ExportBindDeviceListVO> voList = new ArrayList<>();
        DeviceObdExFactoryBatchBindInfo bindInfo = deviceObdExFactoryBatchBindInfoService.getById(dto.getId());
        if (bindInfo == null) return;
//        DeviceObdExFactoryBatchInfo batchInfo = deviceObdExFactoryBatchInfoService.getById(bindInfo.getBatchId());
//        String model = "TJ20-2";
//        String model = "";
        Map<Long,String> batchMap = new HashMap<>();
        if(bindInfo.getDtus() == null || "".equals(bindInfo.getDtus()))return;
        String[] dtuStr = bindInfo.getDtus().split(";");
        List<Long> ids = new ArrayList<>();
        for(String dtu:dtuStr){
            if("".equals(dtu))continue;
            ids.add(Long.valueOf(dtu));
        }
        if(ids.size()==0)return;
        GetDeviceObdBaseInfoDO getDeviceObdBaseInfoDO = new GetDeviceObdBaseInfoDO();
        getDeviceObdBaseInfoDO.setIds(ids);
        getDeviceObdBaseInfoDO.setSortRow("cartonNo");
        List<DeviceObdBaseInfo> baseList = deviceObdBaseInfoService.getAllList(getDeviceObdBaseInfoDO);
        if (baseList != null && baseList.size() > 0) {
            System.out.println("====baseList :" + baseList.size());
            for (DeviceObdBaseInfo item : baseList) {
                String model = "";
                if(batchMap.get(item.getBatchId()) == null){
                    DeviceObdExFactoryBatchInfo batchInfo = deviceObdExFactoryBatchInfoService.getById(item.getBatchId());
                    if (batchInfo!=null && batchInfo.getModelId() != null && batchInfo.getModelId() != 0) {
                        SystemDeviceModelInfo modelInfo = systemDeviceModelInfoService.getById(batchInfo.getModelId());
                        if (modelInfo != null) model = modelInfo.getName();
                        batchMap.put(batchInfo.getBatchId(),model);
                    }
                }else{
                    model = batchMap.get(item.getBatchId());
                }
                ExportBindDeviceListVO vo = new ExportBindDeviceListVO();
                vo.setFactoryCode("");//终端类型
                vo.setImei(item.getImei());//IMEI号
                vo.setModelName(model);
                vo.setDtu(item.getDtu());
                vo.setMachineCode("");
                voList.add(vo);
            }
        }
        String fileName = "obd_device_list_" + DateUtils.parseDateToStr(DateUtils.YYYYMMDD_HHMM, new Date());
        try {
            System.out.println("====voList :" + voList.size());
            ExcelUtil.writeExcel(response, voList, fileName, "OBD设备信息", new ExportBindDeviceListVO());
        } catch (IOException e) {
            e.printStackTrace();
            log.error("导出失败，文件名:{}", fileName);
        }
    }

    @Log(title = "生产厂商管理 -  保存环保帐号信息", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "保存环保帐号信息")
    @PostMapping(value = "/saveVeccAccountInfo")
    public Result<Objects> saveVeccAccountInfo(@RequestBody @Valid SaveVeccAccountInfoDTO dto){
        LoginUserDetails loginUserDetails = SecurityUtils.getLoginUser();
        long factoryUserId = loginUserDetails.getUser().getUserId();
        UserInfo userInfo = userInfoService.getById(factoryUserId);
        if(userInfo == null ){
            return Result.fail("9999","生产厂商不存在");
        }
        userInfo.setCompanyName(dto.getCompanyName());
        userInfo.setCompanyCode(dto.getCompanyCode());
        userInfo.setForwardAccount(dto.getForwardAccount());
        userInfo.setForwardPwd(dto.getForwardPwd());
        userInfoService.update(userInfo);
        return Result.suc();
    }

    @Log(title = "生产厂商管理 -  获取用户环保帐号信息", businessType = BusinessType.SELECT)
    @ApiOperation(value = "保存环保帐号信息")
    @PostMapping(value = "/getVeccAccountInfo")
    public Result<GetVeccAccountInfoVO> getVeccAccountInfo(){
        GetVeccAccountInfoVO vo = new GetVeccAccountInfoVO();
        LoginUserDetails loginUserDetails = SecurityUtils.getLoginUser();
        if(loginUserDetails.getUser()==null){
            return Result.fail("9999","生产厂商不存在");
        }
        long factoryUserId = loginUserDetails.getUser().getUserId();
        UserInfo userInfo = userInfoService.getById(factoryUserId);
        if(userInfo == null ){
            return Result.fail("9999","生产厂商不存在");
        }
        String companyName = "";
        String companyCode = "";
        String forwardAccount = "";
        String forwardPwd = "";
        if(StringUtils.isNotBlank(userInfo.getCompanyName()))companyName = userInfo.getCompanyName();
        if(StringUtils.isNotBlank(userInfo.getCompanyCode())) companyCode = userInfo.getCompanyCode();
        if(StringUtils.isNotBlank(userInfo.getForwardAccount())) forwardAccount = userInfo.getForwardAccount();
        if(StringUtils.isNotBlank(userInfo.getForwardPwd())) forwardPwd = userInfo.getForwardPwd();
        vo.setCompanyName(companyName);
        vo.setCompanyCode(companyCode);
        vo.setForwardAccount(forwardAccount);
        vo.setForwardPwd(forwardPwd);
        return Result.suc(vo);
    }
}
